<template>
  <div class="chat-container">
    <div class="chat-history">
      <div v-for="(message, index) in messages" :key="index" :class="['message', message.type]">
        {{ message.content }}
      </div>
    </div>
    <div class="input-area" :style="{ bottom: bottomHeight + 'px' }">
      <input v-model="inputMessage" @keyup.enter="sendMessage" placeholder="请输入消息" />
      <button @click="sendMessage" :disabled="sseConnected">发送</button>
    </div>
  </div>
</template>

<script setup lang="ts">

onShareAppMessage(() => ({
  title: 'sse演示',
  path: '/pagesA/sse/index'
}));

// 状态定义
const messages = ref<{
  type: string,
  content: string
}[]>([]);
const inputMessage = ref('');
const sse = ref();
const sseConnected = ref(false);
const bufferText = ref('')
const bottomHeight = ref(0)
// 发送消息
const sendMessage = () => {
  if (!inputMessage.value.trim()) return;

  // 添加用户消息
  messages.value.push({
    type: 'user',
    content: inputMessage.value,
  });
  inputMessage.value = '';
  scrollToBottom();

  // 连接SSE
  connectToSSE();
};

const decodedString = (uint8Array: Uint8Array): string => {
  let txt = '';
  // 1.获取对象的准确的类型
  const type = Object.prototype.toString.call(uint8Array);
  if (type === "[object Uint8Array]") {
    txt = decodeURIComponent(escape(String.fromCharCode(...uint8Array)));
  } else if (uint8Array instanceof ArrayBuffer) {
    const arr = new Uint8Array(uint8Array);
    txt = decodeURIComponent(escape(String.fromCharCode(...arr)));
  }
  return txt;
}

// 连接SSE
const connectToSSE = () => {
  if (sseConnected.value) return
  sseConnected.value = true;

  // 添加正在输入提示
  const msgObj = {
    type: 'bot',
    content: '正在思考...',
  }
  messages.value.push(msgObj);
  const requestTask = uni.request({
    url: 'https://api.yinuosnowball.top/api/v1/open-api/chat/message',
    method: 'POST',
    responseType: 'arraybuffer',
    enableChunked: true,
    timeout: 300000,
    complete: () => {
      sseConnected.value = false;
    },
    fail: (err) => {
      console.error('SSE连接失败:', err);
      sseConnected.value = false;
      messages.value.push({
        type: 'system',
        content: `连接失败: ${err.errMsg}`
      });
    }
  });
  requestTask.onChunkReceived((res) => {
    console.log(res)
    const chunk = res.data;
    const text = decodedString(chunk);
    let arr = text.split('\n\n').filter(Boolean)
    console.log('打印***arr', arr)
    try {
      arr.forEach(async msg => {
        const jsonStr = "\"" + msg.substring(13); // 去掉 'data: ' 前缀
        console.log('打印***jsonStr', jsonStr)
        const data = JSON.parse(JSON.parse(jsonStr));
        console.log('打印***data', data)
        switch (data.event) {
          case 'message': {
            // 处理文本消息
            console.log('打印***data.answer', data.answer)
            // 查找是否存在相同ID的消息
            const msg = messages.value[messages.value.length - 1].content
            if (msg === '正在思考...') {
              messages.value[messages.value.length - 1].content = data.answer;
            } else {
              messages.value[messages.value.length - 1].content += data.answer;
            }
            scrollToBottom();
            break;
          }
          case 'message_end': {
            // 消息结束
            sseConnected.value = false;
            break;
          }
        }
      });
    } catch (error) {
      console.error('解析数据失败:', error);
    }
  })
};

onMounted(() => {
  // 获取键盘高度
  uni.onKeyboardHeightChange((res) => {
    console.log('打印***height', res)
    bottomHeight.value = res.height ? res.height - 2 : 0
  })
})

// 滚动到底部
const scrollToBottom = () => {
  uni.pageScrollTo({
    scrollTop: 9999999999999999,
    duration: 300,
    selector: '.chat-container'
  })

};

</script>

<style scoped>
.chat-container {
  max-width: 600px;
  margin: 0 auto;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - 90px);
  padding-bottom: 80px;
  /* 设置容器高度为视口高度 */
}

.message {
  margin: 10px;
  padding: 8px 12px;
  border-radius: 12px;
  /* 添加消息圆角 */
  max-width: 80%;
}

.chat-history {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
  background-color: #f9f9f9;
  padding-bottom: 80px;
  /* 添加底部内边距避免被输入框遮挡 */
}

.message {
  margin: 10px;
  padding: 8px 12px;
  border-radius: 12px;
  /* 添加消息圆角 */
  max-width: 80%;
}

.user {
  background-color: #dcf8c6;
  margin-left: auto;
}

.bot {
  background-color: #fff;
  margin-right: auto;
}

.system {
  background-color: #e3e3e3;
  margin: 10px auto;
  text-align: center;
  font-size: 0.9em;
  color: #666;
  border-radius: 8px;
  /* 添加系统消息圆角 */
}

.input-area {
  display: flex;
  padding: 10px;
  background-color: #eee;
  border-top: 1px solid #ccc;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  max-width: 600px;
  margin: 0 auto;
  box-sizing: border-box;
  /* 确保padding不会增加宽度 */
}

.input-area input {
  flex: 1;
  padding: 8px;
  margin-right: 10px;
  border: 1px solid #ccc;
  border-radius: 8px;
  /* 添加输入框圆角 */
}

.input-area button {
  padding: 8px 16px;
  background-color: #007aff;
  color: white;
  border: none;
  border-radius: 8px;
  /* 添加按钮圆角 */
  cursor: pointer;
  margin-left: 5px;
}

.input-area button:hover {
  background-color: #0056b3;
}
</style>
